package com.school.sports.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.school.sports.entity.Message;
import com.school.sports.service.MessageService;
import com.school.sports.common.Result;
import com.school.sports.util.WebSocketUtil;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;


import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

/**
 * 消息通知控制器
 * 提供系统消息管理、消息推送、消息中心、消息统计、消息撤回等功能
 */
@RestController
@RequestMapping("/api/messages")
public class MessageController {

    private static final Logger logger = LoggerFactory.getLogger(MessageController.class);

    @Autowired
    private MessageService messageService;

    // ==================== 基础消息管理 ====================

    /**
     * 分页查询消息列表
     * @param currentPage 当前页码
     * @param pageSize 每页显示数量
     * @param message 查询条件对象
     * @return 包含分页数据的Result对象
     */
    @GetMapping("/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<IPage<Message>> getMessagePage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            Message message) {

        logger.info("分页查询消息列表，当前页码：{}，每页条数：{}，查询条件：{}", currentPage, pageSize, message);

        // 参数校验
        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<Message> page = messageService.getPage(currentPage, pageSize, message);

            // 如果当前页码超过总页数，获取最后一页数据
            if (currentPage > page.getPages() && page.getPages() > 0) {
                page = messageService.getPage((int) page.getPages(), pageSize, message);
            }

            logger.info("查询消息列表成功，共{}条记录，当前第{}页", page.getTotal(), page.getCurrent());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询消息列表异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据ID查询消息详情
     * @param messageId 消息ID
     * @return 消息详情
     */
    @GetMapping("/{messageId}")
    public Result<Message> getMessageById(@PathVariable("messageId") Long messageId) {
        logger.info("查询消息详情，消息ID：{}", messageId);

        if (messageId == null || messageId <= 0) {
            return Result.fail("消息ID无效");
        }

        try {
            // 获取当前用户ID
            Long currentUserId = getCurrentUserId();
            if (currentUserId == null) {
                return Result.fail("用户未登录");
            }

            Message message = messageService.getMessageDetail(messageId, currentUserId);
            if (message == null) {
                return Result.fail("消息不存在或无权查看");
            }

            logger.info("查询消息详情成功，消息ID：{}", messageId);
            return Result.success(message);
        } catch (Exception e) {
            logger.error("查询消息详情异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    // ==================== 系统消息管理 ====================

    /**
     * 发送系统消息
     * @param message 消息对象
     * @param userId 接收者用户ID
     * @return 发送结果
     */
    @PostMapping("/system/send/{userId}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Message> sendSystemMessage(
            @Valid @RequestBody Message message,
            @PathVariable("userId") Long userId) {

        logger.info("发送系统消息，接收者用户ID：{}，消息标题：{}", userId, message.getTitle());

        if (userId == null || userId <= 0) {
            return Result.fail("接收者用户ID无效");
        }

        try {
            Message sentMessage = messageService.sendSystemMessage(
                message.getTitle(), message.getContent(), userId);

            if (sentMessage != null) {
                // 通过WebSocket发送新消息通知
                WebSocketUtil.sendNewMessage(sentMessage, String.valueOf(userId));


                // 1. 定义日期时间格式（按需调整格式，如包含秒、毫秒等）
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                // 2. 将 LocalDateTime 格式化为 String（处理 null 避免空指针）
                String createTimeStr = sentMessage.getCreatedAt() != null
                        ? sentMessage.getCreatedAt().format(formatter)
                        : "未知时间";




                // 发送系统消息状态更新给管理员
                WebSocketUtil.sendMessageStatusUpdate(
                    sentMessage.getId(),
                    sentMessage.getTitle(),
                    "sent",
                    createTimeStr,
                    1
                );

                logger.info("发送系统消息成功，消息ID：{}", sentMessage.getId());
                return Result.success(sentMessage);
            } else {
                return Result.fail("发送系统消息失败");
            }
        } catch (Exception e) {
            logger.error("发送系统消息异常：{}", e.getMessage(), e);
            return Result.fail("发送失败：" + e.getMessage());
        }
    }

    /**
     * 批量发送系统消息
     * @param message 消息对象
     * @param userIds 接收者用户ID列表
     * @return 发送结果
     */
    @PostMapping("/system/batch-send")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> batchSendSystemMessage(
            @Valid @RequestBody Message message,
            @RequestParam("userIds") List<Long> userIds) {

        logger.info("批量发送系统消息，接收者数量：{}，消息标题：{}", userIds.size(), message.getTitle());

        if (userIds == null || userIds.isEmpty()) {
            return Result.fail("接收者用户ID列表不能为空");
        }

        try {
            int count = messageService.batchSendSystemMessage(
                message.getTitle(), message.getContent(), userIds);

            // 通过WebSocket群发新消息通知
            String[] userIdStrings = userIds.stream()
                    .map(String::valueOf)
                    .toArray(String[]::new);

            // 创建临时消息对象用于WebSocket通知
            Message tempMessage = new Message();
            tempMessage.setTitle(message.getTitle());
            tempMessage.setContent(message.getContent());
            tempMessage.setType("system");
            // 处理优先级转换
            if ("high".equals(message.getPriority())) {
                tempMessage.setPriority(1);
            } else if ("medium".equals(message.getPriority())) {
                tempMessage.setPriority(2);
            } else if ("low".equals(message.getPriority())) {
                tempMessage.setPriority(3);
            } else {
                tempMessage.setPriority(2); // 默认中等优先级
            }
            tempMessage.setCreatedAt(LocalDateTime.now());

            WebSocketUtil.sendNewMessage(tempMessage, userIdStrings);

            // 发送系统消息状态更新给管理员
            WebSocketUtil.sendMessageStatusUpdate(
                null,
                message.getTitle(),
                "sent",
                new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()),
                count
            );

            logger.info("批量发送系统消息成功，共发送{}条消息", count);
            return Result.success("批量发送成功，共发送" + count + "条消息");
        } catch (Exception e) {
            logger.error("批量发送系统消息异常：{}", e.getMessage(), e);
            return Result.fail("批量发送失败：" + e.getMessage());
        }
    }

    /**
     * 广播系统消息给所有用户
     * @param message 消息对象
     * @return 发送结果
     */
    @PostMapping("/system/broadcast")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> broadcastSystemMessage(@Valid @RequestBody Message message) {
        logger.info("广播系统消息，消息标题：{}", message.getTitle());

        try {
            boolean success = messageService.broadcastSystemMessage(
                message.getTitle(), message.getContent());

            if (success) {

                // 创建临时消息对象用于WebSocket广播
                Message tempMessage = new Message();
                tempMessage.setTitle(message.getTitle());
                tempMessage.setContent(message.getContent());
                tempMessage.setType("announcement");
                // 关键修改：将字符串优先级转为对应的Integer值
                tempMessage.setPriority("high".equals("high") ? 1 : 2); // 直接写死"high"对应1，或根据变量判断
                tempMessage.setCreatedAt(LocalDateTime.now());

                // 通过WebSocket群发新消息通知给所有在线用户
                WebSocketUtil.sendNewMessageToAll(tempMessage);

                // 发送新系统消息通知给管理员
                WebSocketUtil.sendNewSystemMessage(
                    null,
                    message.getTitle(),
                    "announcement",
                    "high"
                );

                logger.info("广播系统消息成功");
                return Result.success("广播成功");
            } else {
                return Result.fail("广播失败");
            }
        } catch (Exception e) {
            logger.error("广播系统消息异常：{}", e.getMessage(), e);
            return Result.fail("广播失败：" + e.getMessage());
        }
    }

    // ==================== 消息推送接口 ====================

    /**
     * 推送消息到指定用户
     * @param message 消息对象
     * @param userId 用户ID
     * @return 推送结果
     */
    @PostMapping("/push/{userId}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> pushNotificationToUser(
            @Valid @RequestBody Message message,
            @PathVariable("userId") Long userId) {

        logger.info("推送消息到用户，用户ID：{}，消息标题：{}", userId, message.getTitle());

        if (userId == null || userId <= 0) {
            return Result.fail("用户ID无效");
        }

        try {
            boolean success = messageService.pushNotificationToUser(
                message.getTitle(), message.getContent(), userId);

            if (success) {
                // 创建临时消息对象用于WebSocket推送
                Message tempMessage = new Message();
                tempMessage.setTitle(message.getTitle());
                tempMessage.setContent(message.getContent());
                tempMessage.setType(message.getType() != null ? message.getType() : "notification");

                // 处理优先级：将 Integer 转为 String 后再映射为 Integer（1-高，2-中，3-低）
                String priorityStr = message.getPriority() != null ? message.getPriority().toString() : "medium";
                Integer priority;
                switch (priorityStr) {
                    case "1":  // 注意：此时 priorityStr 是 "1" 而非 "high"（因为原 priority 是 Integer）
                    case "high":  // 兼容可能的字符串输入
                        priority = 1;
                        break;
                    case "3":
                    case "low":
                        priority = 3;
                        break;
                    default:  // 包括 "2"、"medium" 或其他情况
                        priority = 2;
                }
                tempMessage.setPriority(priority);

                tempMessage.setCreatedAt(LocalDateTime.now());

                // 通过WebSocket发送新消息通知
                WebSocketUtil.sendNewMessage(tempMessage, String.valueOf(userId));

                // 发送推送状态更新给管理员
                WebSocketUtil.sendPushStatusUpdate(
                    null,
                    message.getTitle(),
                    "success",
                    new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()),
                    null
                );

                logger.info("推送消息成功，用户ID：{}", userId);
                return Result.success("推送成功");
            } else {
                // 推送失败，发送失败状态
                WebSocketUtil.sendPushStatusUpdate(
                    null,
                    message.getTitle(),
                    "failed",
                    new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()),
                    "推送服务异常"
                );

                return Result.fail("推送失败");
            }
        } catch (Exception e) {
            logger.error("推送消息异常：{}", e.getMessage(), e);

            // 推送异常，发送失败状态
            WebSocketUtil.sendPushStatusUpdate(
                null,
                message.getTitle(),
                "failed",
                new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()),
                e.getMessage()
            );

            return Result.fail("推送失败：" + e.getMessage());
        }
    }

    /**
     * 批量推送消息
     * @param message 消息对象
     * @param userIds 用户ID列表
     * @return 推送结果
     */
    @PostMapping("/push/batch")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> batchPushNotification(
            @Valid @RequestBody Message message,
            @RequestParam("userIds") List<Long> userIds) {

        logger.info("批量推送消息，用户数量：{}，消息标题：{}", userIds.size(), message.getTitle());

        if (userIds == null || userIds.isEmpty()) {
            return Result.fail("用户ID列表不能为空");
        }

        try {
            boolean success = messageService.batchPushNotification(message, userIds);

            if (success) {
                logger.info("批量推送消息成功，用户数量：{}", userIds.size());
                return Result.success("批量推送成功");
            } else {
                return Result.fail("批量推送失败");
            }
        } catch (Exception e) {
            logger.error("批量推送消息异常：{}", e.getMessage(), e);
            return Result.fail("批量推送失败：" + e.getMessage());
        }
    }

    /**
     * 推送审核结果消息
     * @param message 消息对象
     * @param userId 用户ID
     * @param extraData 扩展数据
     * @return 推送结果
     */
    @PostMapping("/push/audit-result/{userId}")
    @PreAuthorize("hasAnyRole('管理员', '老师', '裁判')")
    public Result<String> pushAuditResult(
            @Valid @RequestBody Message message,
            @PathVariable("userId") Long userId,
            @RequestParam(value = "extraData", required = false) String extraData) {

        logger.info("推送审核结果消息，用户ID：{}，消息标题：{}", userId, message.getTitle());

        if (userId == null || userId <= 0) {
            return Result.fail("用户ID无效");
        }

        try {
            boolean success = messageService.pushAuditResult(
                message.getTitle(), message.getContent(), userId, extraData);

            if (success) {
                logger.info("推送审核结果消息成功，用户ID：{}", userId);
                return Result.success("推送成功");
            } else {
                return Result.fail("推送失败");
            }
        } catch (Exception e) {
            logger.error("推送审核结果消息异常：{}", e.getMessage(), e);
            return Result.fail("推送失败：" + e.getMessage());
        }
    }

    /**
     * 推送赛程变更消息
     * @param message 消息对象
     * @param userIds 用户ID列表
     * @param linkUrl 相关链接
     * @return 推送结果
     */
    @PostMapping("/push/schedule-change")
    @PreAuthorize("hasAnyRole('管理员', '老师', '裁判')")
    public Result<String> pushScheduleChange(
            @Valid @RequestBody Message message,
            @RequestParam("userIds") List<Long> userIds,
            @RequestParam(value = "linkUrl", required = false) String linkUrl) {

        logger.info("推送赛程变更消息，用户数量：{}，消息标题：{}", userIds.size(), message.getTitle());

        if (userIds == null || userIds.isEmpty()) {
            return Result.fail("用户ID列表不能为空");
        }

        try {
            boolean success = messageService.pushScheduleChange(
                message.getTitle(), message.getContent(), userIds, linkUrl);

            if (success) {
                logger.info("推送赛程变更消息成功，用户数量：{}", userIds.size());
                return Result.success("推送成功");
            } else {
                return Result.fail("推送失败");
            }
        } catch (Exception e) {
            logger.error("推送赛程变更消息异常：{}", e.getMessage(), e);
            return Result.fail("推送失败：" + e.getMessage());
        }
    }

    /**
     * 推送获奖通知
     * @param message 消息对象
     * @param userId 用户ID
     * @param extraData 扩展数据
     * @return 推送结果
     */
    @PostMapping("/push/award/{userId}")
    @PreAuthorize("hasAnyRole('管理员', '老师', '裁判')")
    public Result<String> pushAwardNotification(
            @Valid @RequestBody Message message,
            @PathVariable("userId") Long userId,
            @RequestParam(value = "extraData", required = false) String extraData) {

        logger.info("推送获奖通知，用户ID：{}，消息标题：{}", userId, message.getTitle());

        if (userId == null || userId <= 0) {
            return Result.fail("用户ID无效");
        }

        try {
            boolean success = messageService.pushAwardNotification(
                message.getTitle(), message.getContent(), userId, extraData);

            if (success) {
                logger.info("推送获奖通知成功，用户ID：{}", userId);
                return Result.success("推送成功");
            } else {
                return Result.fail("推送失败");
            }
        } catch (Exception e) {
            logger.error("推送获奖通知异常：{}", e.getMessage(), e);
            return Result.fail("推送失败：" + e.getMessage());
        }
    }

    /**
     * 推送紧急通知
     * @param message 消息对象
     * @param userIds 用户ID列表
     * @return 推送结果
     */
    @PostMapping("/push/urgent")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> pushUrgentNotification(
            @Valid @RequestBody Message message,
            @RequestParam("userIds") List<Long> userIds) {

        logger.info("推送紧急通知，用户数量：{}，消息标题：{}", userIds.size(), message.getTitle());

        if (userIds == null || userIds.isEmpty()) {
            return Result.fail("用户ID列表不能为空");
        }

        try {
            boolean success = messageService.pushUrgentNotification(
                message.getTitle(), message.getContent(), userIds);

            if (success) {
                logger.info("推送紧急通知成功，用户数量：{}", userIds.size());
                return Result.success("推送成功");
            } else {
                return Result.fail("推送失败");
            }
        } catch (Exception e) {
            logger.error("推送紧急通知异常：{}", e.getMessage(), e);
            return Result.fail("推送失败：" + e.getMessage());
        }
    }

    // ==================== 消息中心接口 ====================

    /**
     * 获取用户消息列表
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @param messageType 消息类型（可选）
     * @param isRead 是否已读（可选）
     * @param limit 限制数量（可选）
     * @return 消息列表
     */
    @GetMapping("/center/list")
    public Result<List<Message>> getUserMessages(
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "messageType", required = false) String messageType,
            @RequestParam(value = "isRead", required = false) Integer isRead,
            @RequestParam(value = "limit", required = false) Integer limit) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取用户消息列表，用户ID：{}，消息类型：{}，阅读状态：{}，限制数量：{}",
                   userId, messageType, isRead, limit);

        try {
            List<Message> messages = messageService.getUserMessages(
                userId, messageType, isRead, limit);

            logger.info("获取用户消息列表成功，用户ID：{}，消息数量：{}", userId, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("获取用户消息列表异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户未读消息列表
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 未读消息列表
     */
    @GetMapping("/center/unread")
    public Result<List<Message>> getUnreadMessages(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取用户未读消息列表，用户ID：{}", userId);

        try {
            List<Message> messages = messageService.getUnreadMessages(userId);

            logger.info("获取用户未读消息列表成功，用户ID：{}，未读消息数量：{}", userId, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("获取用户未读消息列表异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户已读消息列表
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @param limit 限制数量
     * @return 已读消息列表
     */
    @GetMapping("/center/read")
    public Result<List<Message>> getReadMessages(
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "limit", defaultValue = "20") Integer limit) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取用户已读消息列表，用户ID：{}，限制数量：{}", userId, limit);

        try {
            List<Message> messages = messageService.getReadMessages(userId, limit);

            logger.info("获取用户已读消息列表成功，用户ID：{}，已读消息数量：{}", userId, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("获取用户已读消息列表异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 按消息类型获取用户消息
     * @param messageType 消息类型
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 消息列表
     */
    @GetMapping("/center/by-type/{messageType}")
    public Result<List<Message>> getMessagesByType(
            @PathVariable("messageType") String messageType,
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("按类型获取用户消息，用户ID：{}，消息类型：{}", userId, messageType);

        try {
            List<Message> messages = messageService.getMessagesByType(userId, messageType);

            logger.info("按类型获取用户消息成功，用户ID：{}，消息类型：{}，消息数量：{}",
                       userId, messageType, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("按类型获取用户消息异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取系统通知列表
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 系统通知列表
     */
    @GetMapping("/center/system-notifications")
    public Result<List<Message>> getSystemNotifications(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取系统通知列表，用户ID：{}", userId);

        try {
            List<Message> messages = messageService.getSystemNotifications(userId);

            logger.info("获取系统通知列表成功，用户ID：{}，通知数量：{}", userId, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("获取系统通知列表异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取紧急消息列表
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 紧急消息列表
     */
    @GetMapping("/center/urgent")
    public Result<List<Message>> getUrgentMessages(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取紧急消息列表，用户ID：{}", userId);

        try {
            List<Message> messages = messageService.getUrgentMessages(userId);

            logger.info("获取紧急消息列表成功，用户ID：{}，紧急消息数量：{}", userId, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("获取紧急消息列表异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取最新消息
     * @param limit 限制数量
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 最新消息列表
     */
    @GetMapping("/center/latest")
    public Result<List<Message>> getLatestMessages(
            @RequestParam(value = "limit", defaultValue = "10") Integer limit,
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取最新消息，用户ID：{}，限制数量：{}", userId, limit);

        try {
            List<Message> messages = messageService.getLatestMessages(userId, limit);

            logger.info("获取最新消息成功，用户ID：{}，消息数量：{}", userId, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("获取最新消息异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 标记消息为已读
     * @param messageId 消息ID
     * @param userId 用户ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @PutMapping("/center/mark-read/{messageId}")
    public Result<String> markAsRead(
            @PathVariable("messageId") Long messageId,
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("标记消息为已读，消息ID：{}，用户ID：{}", messageId, userId);

        if (messageId == null || messageId <= 0) {
            return Result.fail("消息ID无效");
        }

        try {
            boolean success = messageService.markAsRead(messageId, userId);

            if (success) {
                // 通过WebSocket发送消息已读状态更新
                // 这里可以添加具体的WebSocket通知逻辑，例如通知其他管理员该消息已被标记为已读
                // 目前先记录日志，实际项目中可以根据需要添加具体的通知逻辑

                logger.info("标记消息为已读成功，消息ID：{}", messageId);
                return Result.success("标记成功");
            } else {
                return Result.fail("标记失败");
            }
        } catch (Exception e) {
            logger.error("标记消息为已读异常：{}", e.getMessage(), e);
            return Result.fail("标记失败：" + e.getMessage());
        }
    }

    /**
     * 删除用户消息
     * @param messageId 消息ID
     * @param userId 用户ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @DeleteMapping("/center/delete/{messageId}")
    public Result<String> deleteUserMessage(
            @PathVariable("messageId") Long messageId,
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("删除用户消息，消息ID：{}，用户ID：{}", messageId, userId);

        if (messageId == null || messageId <= 0) {
            return Result.fail("消息ID无效");
        }

        try {
            boolean success = messageService.deleteUserMessage(messageId, userId);

            if (success) {
                logger.info("删除用户消息成功，消息ID：{}", messageId);
                return Result.success("删除成功");
            } else {
                return Result.fail("删除失败");
            }
        } catch (Exception e) {
            logger.error("删除用户消息异常：{}", e.getMessage(), e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }

    /**
     * 清空用户消息
     * @param userId 用户ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @DeleteMapping("/center/clear")
    public Result<String> clearUserMessages(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("清空用户消息，用户ID：{}", userId);

        try {
            boolean success = messageService.clearUserMessages(userId);

            if (success) {
                logger.info("清空用户消息成功，用户ID：{}", userId);
                return Result.success("清空成功");
            } else {
                return Result.fail("清空失败");
            }
        } catch (Exception e) {
            logger.error("清空用户消息异常：{}", e.getMessage(), e);
            return Result.fail("清空失败：" + e.getMessage());
        }
    }

    // ==================== 消息统计接口 ====================

    /**
     * 获取用户消息统计
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 消息统计信息
     */
    @GetMapping("/statistics/user")
    public Result<Map<String, Object>> getMessageStatistics(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取用户消息统计，用户ID：{}", userId);

        try {
            Map<String, Object> statistics = messageService.getMessageStatistics(userId);

            logger.info("获取用户消息统计成功，用户ID：{}", userId);
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取用户消息统计异常：{}", e.getMessage(), e);
            return Result.fail("获取统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取各类型消息数量统计
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 消息类型统计
     */
    @GetMapping("/statistics/by-type")
    public Result<Map<String, Integer>> getMessageTypeStatistics(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取消息类型统计，用户ID：{}", userId);

        try {
            Map<String, Integer> statistics = messageService.getMessageTypeStatistics(userId);

            logger.info("获取消息类型统计成功，用户ID：{}", userId);
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取消息类型统计异常：{}", e.getMessage(), e);
            return Result.fail("获取统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取系统消息统计
     * @return 系统消息统计
     */
    @GetMapping("/statistics/system")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Map<String, Object>> getSystemMessageStatistics() {
        logger.info("获取系统消息统计");

        try {
            Map<String, Object> statistics = messageService.getSystemMessageStatistics();

            logger.info("获取系统消息统计成功");
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取系统消息统计异常：{}", e.getMessage(), e);
            return Result.fail("获取统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取每日消息统计
     * @param days 统计天数
     * @return 每日消息统计
     */
    @GetMapping("/statistics/daily")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<Map<String, Object>>> getDailyMessageStatistics(
            @RequestParam(value = "days", defaultValue = "7") Integer days) {

        logger.info("获取每日消息统计，统计天数：{}", days);

        try {
            List<Map<String, Object>> statistics = messageService.getDailyMessageStatistics(days);

            logger.info("获取每日消息统计成功，统计天数：{}", days);
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取每日消息统计异常：{}", e.getMessage(), e);
            return Result.fail("获取统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户消息阅读率
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 阅读率统计
     */
    @GetMapping("/statistics/read-rate")
    public Result<Double> getMessageReadRate(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取用户消息阅读率，用户ID：{}", userId);

        try {
            double readRate = messageService.getMessageReadRate(userId);

            logger.info("获取用户消息阅读率成功，用户ID：{}，阅读率：{}", userId, readRate);
            return Result.success(readRate);
        } catch (Exception e) {
            logger.error("获取用户消息阅读率异常：{}", e.getMessage(), e);
            return Result.fail("获取阅读率失败：" + e.getMessage());
        }
    }

    /**
     * 获取系统消息阅读率
     * @return 系统消息阅读率
     */
    @GetMapping("/statistics/system-read-rate")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Double> getSystemMessageReadRate() {
        logger.info("获取系统消息阅读率");

        try {
            double readRate = messageService.getSystemMessageReadRate();

            logger.info("获取系统消息阅读率成功，阅读率：{}", readRate);
            return Result.success(readRate);
        } catch (Exception e) {
            logger.error("获取系统消息阅读率异常：{}", e.getMessage(), e);
            return Result.fail("获取阅读率失败：" + e.getMessage());
        }
    }

    // ==================== 消息撤回接口 ====================

    /**
     * 撤回消息
     * @param messageId 消息ID
     * @param senderId 发送者ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @PutMapping("/recall/{messageId}")
    public Result<String> recallMessage(
            @PathVariable("messageId") Long messageId,
            @RequestParam(value = "senderId", required = false) Long senderId) {

        // 如果没有指定发送者ID，使用当前用户ID
        if (senderId == null) {
            senderId = getCurrentUserId();
            if (senderId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("撤回消息，消息ID：{}，发送者ID：{}", messageId, senderId);

        if (messageId == null || messageId <= 0) {
            return Result.fail("消息ID无效");
        }

        try {
            // 检查是否可以撤回
            boolean canRecall = messageService.canRecallMessage(messageId, senderId);
            if (!canRecall) {
                return Result.fail("消息无法撤回（可能已超过撤回时间限制或无权限）");
            }

            boolean success = messageService.recallMessage(messageId, senderId);

            if (success) {
                logger.info("撤回消息成功，消息ID：{}", messageId);
                return Result.success("撤回成功");
            } else {
                return Result.fail("撤回失败");
            }
        } catch (Exception e) {
            logger.error("撤回消息异常：{}", e.getMessage(), e);
            return Result.fail("撤回失败：" + e.getMessage());
        }
    }

    /**
     * 批量撤回消息
     * @param messageIds 消息ID列表
     * @param senderId 发送者ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @PutMapping("/recall/batch")
    public Result<String> batchRecallMessages(
            @RequestParam("messageIds") List<Long> messageIds,
            @RequestParam(value = "senderId", required = false) Long senderId) {

        // 如果没有指定发送者ID，使用当前用户ID
        if (senderId == null) {
            senderId = getCurrentUserId();
            if (senderId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("批量撤回消息，消息数量：{}，发送者ID：{}", messageIds.size(), senderId);

        if (messageIds == null || messageIds.isEmpty()) {
            return Result.fail("消息ID列表不能为空");
        }

        try {
            int count = messageService.batchRecallMessages(messageIds, senderId);

            logger.info("批量撤回消息成功，成功撤回{}条消息", count);
            return Result.success("批量撤回成功，共撤回" + count + "条消息");
        } catch (Exception e) {
            logger.error("批量撤回消息异常：{}", e.getMessage(), e);
            return Result.fail("批量撤回失败：" + e.getMessage());
        }
    }

    /**
     * 获取已撤回消息列表
     * @param userId 用户ID（可选，不传则获取当前用户）
     * @return 已撤回消息列表
     */
    @GetMapping("/recalled")
    public Result<List<Message>> getRecalledMessages(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("获取已撤回消息列表，用户ID：{}", userId);

        try {
            List<Message> messages = messageService.getRecalledMessages(userId);

            logger.info("获取已撤回消息列表成功，用户ID：{}，消息数量：{}", userId, messages.size());
            return Result.success(messages);
        } catch (Exception e) {
            logger.error("获取已撤回消息列表异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    // ==================== 批量操作接口 ====================

    /**
     * 批量标记消息为已读
     * @param messageIds 消息ID列表
     * @param userId 用户ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @PutMapping("/batch/mark-read")
    public Result<String> batchMarkAsRead(
            @RequestParam("messageIds") List<Long> messageIds,
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("批量标记消息为已读，消息数量：{}，用户ID：{}", messageIds.size(), userId);

        if (messageIds == null || messageIds.isEmpty()) {
            return Result.fail("消息ID列表不能为空");
        }

        try {
            int count = messageService.batchMarkAsRead(messageIds, userId);

            logger.info("批量标记消息为已读成功，用户ID：{}，标记了{}条消息", userId, count);
            return Result.success("批量标记成功，共标记" + count + "条消息");
        } catch (Exception e) {
            logger.error("批量标记消息为已读异常：{}", e.getMessage(), e);
            return Result.fail("批量标记失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除消息
     * @param messageIds 消息ID列表
     * @param userId 用户ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @DeleteMapping("/batch/delete")
    public Result<String> batchDeleteMessages(
            @RequestParam("messageIds") List<Long> messageIds,
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("批量删除消息，消息数量：{}，用户ID：{}", messageIds.size(), userId);

        if (messageIds == null || messageIds.isEmpty()) {
            return Result.fail("消息ID列表不能为空");
        }

        try {
            int count = messageService.batchDeleteMessages(messageIds, userId);

            logger.info("批量删除消息成功，用户ID：{}，删除了{}条消息", userId, count);
            return Result.success("批量删除成功，共删除" + count + "条消息");
        } catch (Exception e) {
            logger.error("批量删除消息异常：{}", e.getMessage(), e);
            return Result.fail("批量删除失败：" + e.getMessage());
        }
    }

    /**
     * 批量发送自定义消息
     * @param messages 消息列表
     * @return 操作结果
     */
    @PostMapping("/batch/send")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> batchSendMessages(@Valid @RequestBody List<Message> messages) {
        logger.info("批量发送自定义消息，消息数量：{}", messages.size());

        if (messages == null || messages.isEmpty()) {
            return Result.fail("消息列表不能为空");
        }

        try {
            int count = messageService.batchSendMessages(messages);

            logger.info("批量发送自定义消息成功，共发送{}条消息", count);
            return Result.success("批量发送成功，共发送" + count + "条消息");
        } catch (Exception e) {
            logger.error("批量发送自定义消息异常：{}", e.getMessage(), e);
            return Result.fail("批量发送失败：" + e.getMessage());
        }
    }

    /**
     * 标记所有消息为已读
     * @param userId 用户ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @PutMapping("/batch/mark-all-read")
    public Result<String> markAllAsRead(
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("标记所有消息为已读，用户ID：{}", userId);

        try {
            boolean success = messageService.markAllAsRead(userId);

            if (success) {
                logger.info("标记所有消息为已读成功，用户ID：{}", userId);
                return Result.success("标记成功");
            } else {
                return Result.fail("标记失败");
            }
        } catch (Exception e) {
            logger.error("标记所有消息为已读异常：{}", e.getMessage(), e);
            return Result.fail("标记失败：" + e.getMessage());
        }
    }

    /**
     * 批量清空指定类型的消息
     * @param messageType 消息类型
     * @param userId 用户ID（可选，不传则使用当前用户）
     * @return 操作结果
     */
    @DeleteMapping("/batch/clear-by-type")
    public Result<String> clearMessagesByType(
            @RequestParam("messageType") String messageType,
            @RequestParam(value = "userId", required = false) Long userId) {

        // 如果没有指定用户ID，使用当前用户ID
        if (userId == null) {
            userId = getCurrentUserId();
            if (userId == null) {
                return Result.fail("用户未登录");
            }
        }

        logger.info("批量清空指定类型的消息，用户ID：{}，消息类型：{}", userId, messageType);

        try {
            boolean success = messageService.clearMessagesByType(userId, messageType);

            if (success) {
                logger.info("批量清空指定类型的消息成功，用户ID：{}，消息类型：{}", userId, messageType);
                return Result.success("清空成功");
            } else {
                return Result.fail("清空失败");
            }
        } catch (Exception e) {
            logger.error("批量清空指定类型的消息异常：{}", e.getMessage(), e);
            return Result.fail("清空失败：" + e.getMessage());
        }
    }

    // ==================== 辅助方法 ====================

    /**
     * 获取当前登录用户ID
     * @return 用户ID，如果用户未登录则返回null
     */
    private Long getCurrentUserId() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated()) {
                // 假设用户ID存储在认证信息的principal中
                // 实际实现可能需要根据项目的认证机制进行调整
                String username = authentication.getName();
                // 这里应该根据用户名查询用户ID，为了简化示例，暂时返回一个模拟值
                // 实际项目中需要注入UserService或其他服务来获取用户ID
                return 1L; // 这里需要替换为实际的逻辑
            }
        } catch (Exception e) {
            logger.warn("获取当前用户ID失败：{}", e.getMessage());
        }
        return null;
    }
}